<template>
  <view class="page">

    <scroll-view class="content" scroll-y>
      <view class="grid">
        <view class="card" v-for="g in goods" :key="g.id">
          <image class="pic" :src="resolveImg(g.image)" mode="aspectFill" />
          <view class="info">
            <text class="name">{{ g.name }}</text>
            <view class="row">
              <text class="price">{{ formatPoints(g.points) }} 积分</text>
            </view>
          </view>
          <view class="foot">
            <text class="stock">库存 {{ g.quantity || 0 }}</text>
            <view class="ops">
              <button class="minus" v-if="cart[g.id]" @tap="dec(g)">-</button>
              <text class="qty" v-if="cart[g.id]">{{ cart[g.id].quantity }}</text>
              <button class="plus" :disabled="!canBuy(g)" @tap="add(g)">+</button>
            </view>
          </view>
        </view>
      </view>
      <view v-if="!goods.length" class="empty">暂无商品</view>
    </scroll-view>

    <!-- 底部购物车摘要条 -->
    <view class="cart-bar" @tap="toggleCart">
      <view class="cart-left">🛒 <text class="badge" v-if="cartCount">{{ cartCount }}</text></view>
      <view class="cart-mid">合计：<text class="sum">{{ totalPoints }} 积分</text></view>
      <button class="checkout" :disabled="!cartCount" @tap.stop="checkout">结算</button>
    </view>

    <!-- 购物车抽屉 -->
    <view class="mask" v-if="showCart" @tap="toggleCart"></view>
    <view class="drawer" v-if="showCart">
      <view class="drawer-head">
        <text class="drawer-title">我的购物车</text>
        <text class="drawer-close" @tap="toggleCart">×</text>
      </view>
      <scroll-view class="drawer-list" scroll-y>
        <view class="drawer-item" v-for="item in cartItems" :key="item.goods.id">
          <image class="drawer-pic" :src="resolveImg(item.goods.image)" mode="aspectFill" />
          <view class="drawer-info">
            <text class="drawer-name">{{ item.goods.name }}</text>
            <text class="drawer-price">{{ formatPoints(item.goods.points) }} 积分</text>
          </view>
          <view class="drawer-ops">
            <button class="minus" @tap="dec(item.goods)">-</button>
            <text class="qty">{{ item.quantity }}</text>
            <button class="plus" :disabled="item.quantity >= (item.goods.quantity||0)" @tap="add(item.goods)">+</button>
          </view>
        </view>
        <view v-if="!cartItems.length" class="drawer-empty">购物车空空如也</view>
      </scroll-view>
      <view class="drawer-foot">
        <text>合计：</text><text class="sum">{{ totalPoints }} 积分</text>
        <button class="checkout" :disabled="!cartCount" @tap="checkout">结算</button>
      </view>
    </view>
  </view>
  
</template>

<script>
import { listGoods, purchaseGoods } from '@/api/goods'
import config from '@/config'

export default {
  data() {
    return { 
      goods: [],
      cart: {},        // goodsId -> { goods, quantity }
      showCart: false
    }
  },
  onShow() { this.fetchGoods() },
  onLoad() {
    console.log('[value-added] onLoad')
    this.fetchGoods()
  },
  created(){
    console.log('[value-added] created')
  },
  computed: {
    cartItems(){ return Object.values(this.cart) },
    cartCount(){ return this.cartItems.reduce((s,i)=>s + i.quantity, 0) },
    totalPoints(){
      const t = this.cartItems.reduce((s,i)=> s + Number(i.goods.points||0) * i.quantity, 0)
      return Number(t.toFixed(2))
    }
  },
  methods: {
    toggleCart(){ this.showCart = !this.showCart },
    async fetchGoods(){
      console.log('[value-added] fetchGoods start')
      try {
        const res = await listGoods()
        console.log('[value-added] fetchGoods response:', res)
        this.goods = Array.isArray(res.data) ? res.data : (res.rows || res.list || [])
        console.log('[value-added] parsed goods:', this.goods)
        // 兜底：若请求封装被拦截或无数据，直接用 uni.request 请求一次
        if ((!this.goods || this.goods.length === 0) && (typeof res !== 'object' || (res.code === undefined && res.statusCode === undefined))) {
          const base = (config && config.baseUrl) ? String(config.baseUrl).replace(/\/$/, '') : ''
          console.log('[value-added] fallback request ->', base + '/shop/goods/list')
          const r = await new Promise((resolve,reject)=>{
            uni.request({ url: base + '/shop/goods/list', method:'GET', success: resolve, fail: reject })
          })
          console.log('[value-added] fallback response:', r)
          const data = (r.data && (Array.isArray(r.data) ? r.data : (r.data.data || r.data.rows || r.data.list))) || []
          this.goods = Array.isArray(data) ? data : []
        }
      } catch(e) {
        console.error('[value-added] fetchGoods error:', e)
        this.goods = []
        uni.showToast({ title: '获取装备列表失败', icon: 'none' })
      }
    },
    formatPoints(p){
      if (p == null) return 0
      const n = Number(p)
      return isNaN(n) ? p : n
    },
    resolveImg(path){
      const base = (config && config.baseUrl) ? String(config.baseUrl).replace(/\/$/, '') : ''
      const fallback = base ? (base + '/default_good.png') : '/default_good.png'
      if (!path) return fallback
      // http(s) 直链
      if (/^https?:\/\//i.test(path)) return path
      // 数据库存了模块内路径，取文件名拼后端静态资源根
      if (path.indexOf('huangshan-base/src/main/resources/static/') !== -1) {
        const filename = path.split('/').pop()
        return base + '/' + filename
      }
      // 直接给了文件名或 @default_good.png
      if (/default_good\.png$/i.test(path) || /@default_good\.png$/i.test(path)) {
        return fallback
      }
      // 以 / 开头当作后端相对路径
      if (path.startsWith('/')) return base + path
      // 其他相对路径也拼到后端根
      return base + '/' + path
    },
    canBuy(g) {
      const qty = Number(g && g.quantity != null ? g.quantity : 0)
      return !Number.isNaN(qty) && qty > 0
    },
    add(g){
      if (!this.canBuy(g)) { uni.showToast({ title: '库存不足', icon: 'none' }); return }
      const cur = this.cart[g.id]?.quantity || 0
      if (cur + 1 > (g.quantity || 0)) { uni.showToast({ title: '超出库存', icon: 'none' }); return }
      this.$set(this.cart, g.id, { goods: g, quantity: cur + 1 })
    },
    dec(g){
      const cur = this.cart[g.id]?.quantity || 0
      if (cur <= 1) { this.$delete(this.cart, g.id); return }
      this.$set(this.cart, g.id, { goods: g, quantity: cur - 1 })
    },
    async checkout(){
      if (!this.cartCount) return
      const total = this.totalPoints
      const ok = await new Promise(r=>{
        uni.showModal({ title: '确认结算', content: `共 ${this.cartCount} 件，消耗 ${total} 积分，是否支付？`, success: m=>r(!!m.confirm) })
      })
      if (!ok) return
      try{
        uni.showLoading({ title: '支付中...' })
        // 简化：逐件购买，后台单品扣积分+扣库存
        for (const it of this.cartItems) {
          for (let i=0;i<it.quantity;i++) {
            const res = await purchaseGoods(it.goods.id)
            if (!res || res.code !== 200) throw new Error(res?.msg || '购买失败')
          }
        }
        uni.hideLoading()
        uni.showToast({ title: '支付成功', icon: 'success' })
        this.cart = {}
        this.fetchGoods()
        this.showCart = false
        uni.showModal({
          title: '温馨提示',
          content: '请到游客中心出示订单号领取',
          showCancel: false,
          success: () => {
            uni.switchTab({ url: '/pages/order/list' })
          }
        })
      }catch(e){
        uni.hideLoading()
        const msg = (e && e.message) ? String(e.message) : ''
        const lowBalance = /余额不足|积分不足|balance|insufficient/i.test(msg)
        if (lowBalance) {
          uni.showModal({
            title: '支付失败',
            content: '账户余额不足，请充值',
            showCancel: false
          })
        } else {
          uni.showModal({
            title: '支付失败',
            content: msg || '支付失败，请稍后重试',
            showCancel: false
          })
        }
      }
    }
  }
}
</script>

<style scoped>
.page { background:#f7fafc; min-height:100vh; padding-bottom: 160rpx; }
.appbar { height: 88rpx; display:flex; align-items:center; justify-content:space-between; padding:0 24rpx; background:#fff; border-bottom:1rpx solid #e5e7eb; }
.left,.right { width:60rpx; height:60rpx; display:flex; align-items:center; justify-content:center; position: relative; }
.back { font-size:48rpx; color:#374151; font-weight:300; }
.title { font-size:32rpx; font-weight:700; color:#111827; }
.cart-badge { position:absolute; top:-6rpx; right:-6rpx; background:#ef4444; color:#fff; border-radius:999rpx; padding: 2rpx 8rpx; font-size:20rpx; }

.content { min-height: calc(100vh - 160rpx); padding: 16rpx; }
.grid { display: grid; grid-template-columns: repeat(2, 1fr); grid-gap: 16rpx; }
.card { background:#fff; border-radius:16rpx; overflow:hidden; box-shadow:0 6rpx 18rpx rgba(0,0,0,.06); position: relative; }
.pic { width:100%; height:220rpx; background:#eef2f7; }
.info { padding: 12rpx; }
.name { display:block; font-size:26rpx; font-weight:700; color:#111; line-height:1.3; height: 68rpx; overflow:hidden; }
.row { display:flex; align-items:center; justify-content:space-between; margin-top:6rpx; }
.price { color:#0ea5a5; font-weight:700; font-size:26rpx; }
.stock { color:#6b7280; font-size:22rpx; }
.foot { display:flex; align-items:center; justify-content:space-between; padding: 0 12rpx 12rpx 12rpx; }
.ops { display:flex; align-items:center; gap: 12rpx; }
.plus, .minus { width:48rpx; height:48rpx; border-radius:50%; border:none; color:#fff; font-size:28rpx; line-height:48rpx; text-align:center; }
.plus { background:#0ea5a5; }
.minus { background:#94a3b8; }
.qty { min-width: 32rpx; text-align:center; font-weight:700; }

.empty { text-align:center; color:#9ca3af; padding: 80rpx 0; }

.cart-bar { position: fixed; left:0; right:0; bottom:0; display:flex; align-items:center; justify-content:space-between; padding: 12rpx 16rpx; background:#fff; box-shadow:0 -6rpx 20rpx rgba(0,0,0,.08); }
.cart-left { font-size:30rpx; position:relative; }
.badge { background:#ef4444; color:#fff; border-radius:999rpx; padding: 0 10rpx; margin-left: 6rpx; font-size:20rpx; }
.cart-mid { color:#6b7280; }
.sum { color:#0ea5a5; font-weight:700; }
.checkout { background:#16a34a; color:#fff; border:none; border-radius:12rpx; padding: 12rpx 28rpx; }
.checkout[disabled] { background:#d1d5db; color:#9ca3af; }

.mask { position: fixed; left:0; top:0; right:0; bottom:0; background: rgba(0,0,0,.35); }
.drawer { position: fixed; left:0; right:0; bottom:0; background:#fff; border-top-left-radius:16rpx; border-top-right-radius:16rpx; max-height: 70vh; display:flex; flex-direction:column; }
.drawer-head { display:flex; align-items:center; justify-content:space-between; padding: 16rpx; border-bottom:1rpx solid #f0f0f0; }
.drawer-title { font-weight:700; }
.drawer-close { font-size:40rpx; padding: 0 12rpx; }
.drawer-list { flex:1; padding: 8rpx 16rpx; }
.drawer-item { display:flex; align-items:center; padding: 12rpx 0; border-bottom:1rpx solid #f6f6f6; }
.drawer-item:last-child { border-bottom:none; }
.drawer-pic { width:96rpx; height:96rpx; border-radius:8rpx; background:#eef2f7; }
.drawer-info { flex:1; margin-left:12rpx; }
.drawer-name { display:block; font-size:26rpx; font-weight:600; }
.drawer-price { display:block; color:#0ea5a5; margin-top:6rpx; }
.drawer-ops { display:flex; align-items:center; gap:12rpx; }
.drawer-foot { display:flex; align-items:center; justify-content:space-between; padding: 12rpx 16rpx; border-top:1rpx solid #f0f0f0; }
</style>


